// Fill out your copyright notice in the Description page of Project Settings.


#include "ImageTool/CommonImageTool.h"

void UCommonImageTool::ImportImageWithPath(const FString& ImagePath, UTexture2D*& ImgObj, int32& OutWidth,
                                           int32& OutHeight, TArray<uint8>& ImgBin, FEImageFormat& ImgFormat)
{
	if (ImagePath.IsEmpty())
	{
		return;
	}

	if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*ImagePath))
	{
		return;
	}

	if (!FFileHelper::LoadFileToArray(ImgBin, *ImagePath))
	{
		return;
	}

	EImageFormat Imgfmt = EImageFormat::Invalid;
	
	const TSharedPtr<IImageWrapper> ImageWrapper = GetImageWrapperByExtention(ImagePath, Imgfmt);

	switch (Imgfmt)
	{
	case EImageFormat::PNG:
		{
			ImgFormat = FEImageFormat::PNG;
		}
		break;
	case EImageFormat::JPEG:
		{
			ImgFormat = FEImageFormat::JPEG;
		}
		break;
	case EImageFormat::BMP:
		{
			ImgFormat = FEImageFormat::BMP;
		}
		break;
	case EImageFormat::ICO:
		{
			ImgFormat = FEImageFormat::ICO;
		}
		break;
	case EImageFormat::EXR:
		{
			ImgFormat = FEImageFormat::EXR;
		}
		break;
	case EImageFormat::ICNS:
		{
			ImgFormat = FEImageFormat::ICNS;
		}
		break;
		default:
			break;
	}
	
	if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(ImgBin.GetData(), ImgBin.Num()))
	{
		TArray<uint8> UnCompressedRGBA;

		if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UnCompressedRGBA))
		{
			ImgObj = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight());

			if (ImgObj)
			{
				OutWidth = ImageWrapper->GetWidth();
				OutHeight = ImageWrapper->GetHeight();

				void* TextureData = ImgObj->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
				
				FMemory::Memcpy(TextureData, UnCompressedRGBA.GetData(), UnCompressedRGBA.Num());

				ImgObj->GetPlatformData()->Mips[0].BulkData.Unlock();
				ImgObj->UpdateResource();
			}
		}
	}
}

void UCommonImageTool::ImportImageWithBinary(const TArray<uint8>& ImgBin, FEImageFormat ImgFormat, UTexture2D*& ImgObj, int32& OutWidth,
	int32& OutHeight)
{
	if (ImgBin.Num() < 1)
	{
		return;
	}

	TSharedPtr<IImageWrapper> ImageWrapper = GetImageWrapperByExtention(ImgFormat);

	if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(ImgBin.GetData(), ImgBin.Num()))
	{
		TArray<uint8> UnCompressedRGBA;

		if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UnCompressedRGBA))
		{
			ImgObj = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight());

			if (ImgObj)
			{
				OutWidth = ImageWrapper->GetWidth();
				OutHeight = ImageWrapper->GetHeight();

				void* TextureData = ImgObj->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
				
				FMemory::Memcpy(TextureData, UnCompressedRGBA.GetData(), UnCompressedRGBA.Num());

				ImgObj->GetPlatformData()->Mips[0].BulkData.Unlock();
				ImgObj->UpdateResource();
			}
		}
	}
}

TSharedPtr<IImageWrapper> UCommonImageTool::GetImageWrapperByExtention(const FString InImagePath, EImageFormat& ImageFormat)
{
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));

	if (InImagePath.EndsWith(".png"))
	{
		ImageFormat = EImageFormat::PNG;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
	}
	else if (InImagePath.EndsWith(".jpg") || InImagePath.EndsWith(".jpeg"))
	{
		ImageFormat = EImageFormat::JPEG;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
	}
	else if (InImagePath.EndsWith(".bmp"))
	{
		ImageFormat = EImageFormat::BMP;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
	}
	else if (InImagePath.EndsWith(".ico"))
	{
		ImageFormat = EImageFormat::ICO;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICO);
	}
	else if (InImagePath.EndsWith(".exr"))
	{
		ImageFormat = EImageFormat::EXR;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
	}
	else if (InImagePath.EndsWith(".icns"))
	{
		ImageFormat = EImageFormat::ICNS;
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICNS);
	}
	
	return nullptr;
}

TSharedPtr<IImageWrapper> UCommonImageTool::GetImageWrapperByExtention(FEImageFormat ImgFormat)
{
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	
	switch (ImgFormat)
	{
	case FEImageFormat::PNG:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
	case FEImageFormat::JPEG:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
	case FEImageFormat::BMP:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
	case FEImageFormat::ICO:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICO);
	case FEImageFormat::EXR:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
	case FEImageFormat::ICNS:
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICNS);
		default:
			return nullptr;
	}
}
